package com.linkoog.devtools.intellij.ui.table.cell_editor;

import org.jdesktop.swingx.JXDatePicker;
import org.jdesktop.swingx.treetable.AbstractMutableTreeTableNode;

import javax.swing.*;
import javax.swing.table.TableCellEditor;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeCellEditor;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;
import java.util.EventObject;
import java.util.logging.Level;
import java.util.logging.Logger;


public class DatePickerTableCellEditor extends AbstractCellEditor implements TableCellEditor, TreeCellEditor {
    protected JXDatePicker datePicker;
    protected DateFormat dateFormat;
    protected int clickCountToStart;
    private ActionListener pickerActionListener;
    protected boolean ignoreAction;
    private static Logger logger = Logger.getLogger(org.jdesktop.swingx.table.DatePickerCellEditor.class.getName());
    private static final long serialVersionUID = -1L;

    public DatePickerTableCellEditor() {
        this((DateFormat)null);
    }

    public DatePickerTableCellEditor(DateFormat dateFormat) {
        this.clickCountToStart = 2;
        this.dateFormat = dateFormat != null ? dateFormat : DateFormat.getDateInstance();
        this.datePicker = new JXDatePicker();
        this.datePicker.getEditor().setBorder(BorderFactory.createEmptyBorder(0, 1, 0, 1));
        this.datePicker.setFont(UIManager.getDefaults().getFont("TextField.font"));
        if (dateFormat != null) {
            this.datePicker.setFormats(dateFormat);
        }

        this.datePicker.addActionListener(this.getPickerActionListener());
    }

    public Date getCellEditorValue() {
        return this.datePicker.getDate();
    }

    public boolean isCellEditable(EventObject anEvent) {
        if (anEvent instanceof MouseEvent) {
            return ((MouseEvent)anEvent).getClickCount() >= this.getClickCountToStart();
        } else {
            return super.isCellEditable(anEvent);
        }
    }

    public boolean stopCellEditing() {
        this.ignoreAction = true;
        boolean canCommit = this.commitChange();
        this.ignoreAction = false;
        return canCommit ? super.stopCellEditing() : false;
    }

    public void setClickCountToStart(int count) {
        this.clickCountToStart = count;
    }

    public int getClickCountToStart() {
        return this.clickCountToStart;
    }

    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
        this.ignoreAction = true;
        this.datePicker.setDate(this.getValueAsDate(value));
        this.ignoreAction = false;
        return this.datePicker;
    }

    public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) {
        this.ignoreAction = true;
        this.datePicker.setDate(this.getValueAsDate(value));
        this.ignoreAction = false;
        return this.datePicker;
    }

    protected Date getValueAsDate(Object value) {
        if (this.isEmpty(value)) {
            return null;
        } else if (value instanceof Date) {
            return (Date)value;
        } else if (value instanceof Long) {
            return new Date((Long)value);
        } else {
            if (value instanceof String) {
                try {
                    return this.dateFormat.parse((String)value);
                } catch (ParseException var3) {
                    this.handleParseException(var3);
                }
            }

            if (value instanceof DefaultMutableTreeNode) {
                return this.getValueAsDate(((DefaultMutableTreeNode)value).getUserObject());
            } else {
                return value instanceof AbstractMutableTreeTableNode ? this.getValueAsDate(((AbstractMutableTreeTableNode)value).getUserObject()) : null;
            }
        }
    }

    protected void handleParseException(ParseException e) {
        logger.log(Level.SEVERE, e.getMessage(), e.getMessage());
    }

    protected boolean isEmpty(Object value) {
        return value == null || value instanceof String && ((String)value).length() == 0;
    }

    protected boolean commitChange() {
        try {
            this.datePicker.commitEdit();
            return true;
        } catch (ParseException var2) {
            return false;
        }
    }

    public DateFormat[] getFormats() {
        return this.datePicker.getFormats();
    }

    public void setFormats(DateFormat... formats) {
        this.datePicker.setFormats(formats);
    }

    protected ActionListener getPickerActionListener() {
        if (this.pickerActionListener == null) {
            this.pickerActionListener = this.createPickerActionListener();
        }

        return this.pickerActionListener;
    }

    protected ActionListener createPickerActionListener() {
        ActionListener l = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (!DatePickerTableCellEditor.this.ignoreAction) {
                    this.terminateEdit(e);
                }
            }

            private void terminateEdit(ActionEvent e) {
                if (e != null && "datePickerCommit".equals(e.getActionCommand())) {
                    DatePickerTableCellEditor.this.stopCellEditing();
                } else {
                    DatePickerTableCellEditor.this.cancelCellEditing();
                }

            }
        };
        return l;
    }
}